//
//  ZYPurchaseDataBase.m
//  ZYPurchase
//
//  Created by wu on 2020/8/10.
//  Copyright © 2020 wu. All rights reserved.
//

#import "ZYPurchaseDataBase.h"
#import "ZYPurchaseTransactionModel.h"


#import <FMDB/FMDB.h>
#import <MJExtension/MJExtension.h>
#import <SAMKeychain/SAMKeychain.h>

static NSString *const ZYPurchaseTableName = @"PurchaseTable_V1";
static NSString *const ZYPurchaseTableName_receipt = @"receipt_V1";
static NSString *const ZYPurchaseTableName_restore_transaction = @"restore_transaction_V1";

static NSString *const ZYPurchaseSqliteName = @"zypurchase.sqlite";
static NSString *const ZYPurchaseDirectory = @"Purchase";

@interface ZYPurchaseDataBase ()

@end

@implementation ZYPurchaseDataBase (RestoreTransaction)

- (nullable NSDictionary *)fetchTransactionInfoByOriginTransId:(NSString *)originTransId{
    __block NSDictionary *retDict = nil;
    if (!originTransId || (originTransId.length == 0)) {
        return retDict;
    }
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSString *sql = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE trans_origin_id = '%@' limit 0,1", ZYPurchaseTableName_restore_transaction, originTransId];
        FMResultSet *resultSet = [db executeQuery:sql];
        while ([resultSet next]) {
            NSMutableDictionary *dict = @{}.mutableCopy;
            NSString *trans_id = [resultSet stringForColumn:@"trans_id"];
            NSString *trans_origin_id = [resultSet stringForColumn:@"trans_origin_id"];
            NSString *product_id = [resultSet stringForColumn:@"product_id"];
            double trans_time = [resultSet doubleForColumn:@"trans_time"];
            if (trans_id && (trans_id.length > 0)) {
                dict[@"trans_id"] = trans_id;
            }
            if (trans_origin_id && (trans_origin_id.length > 0)) {
                dict[@"trans_origin_id"] = trans_origin_id;
            }
            if (product_id && (product_id.length > 0)) {
                dict[@"product_id"] = product_id;
            }
            dict[@"trans_time"] = @(trans_time);
            retDict = dict;
        }
    }];
    return retDict;
}

// 获取所有原始交易id
- (NSArray *)allOriginTransactionIdInApple{
    __block NSMutableArray *retArr = @[].mutableCopy;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSString *sql = [NSString stringWithFormat:@"SELECT trans_origin_id FROM %@", ZYPurchaseTableName_restore_transaction];
        FMResultSet *resultSet = [db executeQuery:sql];
        while ([resultSet next]) {
            NSString *trans_origin_id = [resultSet stringForColumn:@"trans_origin_id"];
            if (trans_origin_id && (trans_origin_id.length > 0)) {
                [retArr addObject:trans_origin_id];
            }
        }
    }];
    return retArr;
}

// 新增或修改交易信息
- (BOOL)startCache:(NSString *)transId
     originTransId:(NSString *)originTransId
         productId:(NSString *)productId
transDateTimestamp:(double)timestamp
          isUpdate:(BOOL)isUpdate{
    __block BOOL result = NO;
    if (isUpdate) {
        [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
            NSArray *params = @[@"trans_id",
                                @"product_id",
                                @"trans_time"];
            NSString *paramsSqlComp = nil;
            for (NSInteger idx = 0; idx < params.count; idx++) {
                NSString *partComp = [NSString stringWithFormat:@"%@ = ?", params[idx]];
                if (!paramsSqlComp) {
                    paramsSqlComp = partComp;
                } else {
                    paramsSqlComp = [paramsSqlComp stringByAppendingFormat:@", %@", partComp];
                }
            }
            if (!paramsSqlComp) {
                result = NO;
            } else {
                NSString *sql = [NSString stringWithFormat:@"UPDATE %@ SET %@ WHERE trans_origin_id = '%@'", ZYPurchaseTableName_restore_transaction, paramsSqlComp, originTransId];
                result = [db executeUpdate:sql, transId, productId, @(timestamp)];
            }
        }];
    } else {
        [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
            NSArray *params = @[@"trans_id",
                                @"trans_origin_id",
                                @"product_id",
                                @"trans_time"];
            NSString *paramsStr = [params componentsJoinedByString:@", "];
            NSString *valuesStr = @"?";
            if (params.count > 1) {
                for (NSInteger idx = 1; idx < params.count; idx++) {
                    valuesStr = [valuesStr stringByAppendingFormat:@", ?"];
                }
            }
            NSString *sql = [NSString stringWithFormat:@"INSERT INTO %@ (%@) VALUES (%@)", ZYPurchaseTableName_restore_transaction, paramsStr, valuesStr];
            result = [db executeUpdate:sql, transId, originTransId, productId, @(timestamp)];
        }];
    }
    return result;
}

- (BOOL)cacheTransaction:(NSString *)transId
           originTransId:(NSString *)originTransId
               productId:(NSString *)productId
      transDateTimestamp:(double)timestamp{
    return [self startCache:transId
              originTransId:originTransId
                  productId:productId
         transDateTimestamp:timestamp
                   isUpdate:NO];
}

// 检测是否需要，新增或修改交易信息
- (BOOL)cacheTransactionIfNeeded:(NSString *)transId
                   originTransId:(NSString *)originTransId
                       productId:(NSString *)productId
              transDateTimestamp:(double)timestamp{
    NSDictionary *transDict = [self fetchTransactionInfoByOriginTransId:originTransId];
    if (!transDict) {
        return [self startCache:transId
                  originTransId:originTransId
                      productId:productId
             transDateTimestamp:timestamp
                       isUpdate:NO];
    }
    NSString *temp_transId = [transDict objectForKey:originTransId];
    double trans_time = [transDict[@"trans_time"] doubleValue];
    if ((timestamp - trans_time) > 1) {
        return [self startCache:transId
                  originTransId:originTransId
                      productId:productId
             transDateTimestamp:timestamp
                       isUpdate:YES];
    }
    return NO;
}

@end

@implementation ZYPurchaseDataBase

- (instancetype)init{
    self = [super init];
    if (self) {
        [ZYPurchaseDataBase zy_createDirectoryWhenNotExistsAtPath:ZYPurchaseDataBase.purchaseDirectoryPath];
        [ZYPurchaseDataBase zy_createDirectoryWhenNotExistsAtPath:ZYPurchaseDataBase.purchaseReceiptDirectoryPath];
        [ZYPurchaseDataBase zy_createDirectoryWhenNotExistsAtPath:ZYPurchaseDataBase.logFileDirectoryPath];
        
        [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
            NSArray *params = @[@"id integer primary key autoincrement",        // 主键id
                                @"t_status integer",                            // 交易状态
                                @"receipt_data text",                           // 收据
                                @"transaction_id text",                         // 交易id
                                @"order_id text",                               // 订单id
                                @"order_info text",                             // 订单模型json
                                @"payment_method integer",                      // 支付方式
                                @"error text",                                  // 支付失败原因
                                @"uuid text",                                   // 客户端生成的uuid
                                @"create_time double",                          // 交易创建更新时间
                                @"update_time double"                           // 交易上次更新时间
            ];
            NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (%@)", ZYPurchaseTableName, [params componentsJoinedByString:@", "]];
            BOOL result = [db executeUpdate:sql];
            if (!result) {
                NSLog(@"[数据库]  购买表创建成功");
            }
        }];
        
        [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
            NSArray *params = @[@"id integer primary key autoincrement",        // 主键id
                                @"file_name text",                              // 收据文件名称
                                @"order_id text",                               // 订单id
            ];
            NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (%@)", ZYPurchaseTableName_receipt, [params componentsJoinedByString:@", "]];
            BOOL result = [db executeUpdate:sql];
            if (!result) {
                NSLog(@"[数据库]  收据表创建失败");
            }
        }];
        
        [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
            NSArray *params = @[@"id integer primary key autoincrement",        // 主键id
                                @"trans_id text",                              // 交易id
                                @"trans_origin_id text",                        // 原始交易id
                                @"product_id text",                             // 商品id
                                @"trans_time double"                               // 交易时间戳
            ];
            NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (%@)", ZYPurchaseTableName_restore_transaction, [params componentsJoinedByString:@", "]];
            BOOL result = [db executeUpdate:sql];
            if (!result) {
                NSLog(@"[数据库]  收据表创建失败");
            }
        }];
    }
    return self;
}


// MARK: - 查询某条订单的交易是否存在
- (BOOL)existTransactionModel:(nonnull NSString *)orderId{
    __block BOOL result = NO;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSString *sql = [NSString stringWithFormat:@"SELECT order_id FROM %@ WHERE order_id = '%@' limit 0,1", ZYPurchaseTableName, orderId];
        FMResultSet *resultSet = [db executeQuery:sql];
        while ([resultSet next]) {
            result = YES;
        }
    }];
    return result;
}

// MARK: - 根据订单ID获取单条交易
- (ZYPurchaseTransactionModel *)queryTransactionModel:(nonnull NSString *)orderId{
    __block ZYPurchaseTransactionModel *retModel = nil;
    if (!orderId || (orderId.length == 0)) {
        return retModel;
    }
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSString *sql = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE order_id = '%@' limit 0,1", ZYPurchaseTableName, orderId];
        FMResultSet *resultSet = [db executeQuery:sql];
        while ([resultSet next]) {
            retModel = [ZYPurchaseTransactionModel modelFromResultSet:resultSet];
        }
    }];
    return retModel;
}
/// 获取单条订单的交易状态
/// @param orderId 订单id
- (NSInteger)queryTransactionModelTransactionStatus:(nonnull NSString *)orderId{
    __block NSInteger retStatus = ZYPurchaseTransactionStatus_Idle;
    if (!orderId || (orderId.length == 0)) {
        return retStatus;
    }
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSString *sql = [NSString stringWithFormat:@"SELECT order_id, t_status FROM %@ WHERE order_id = '%@' limit 0,1", ZYPurchaseTableName, orderId];
        FMResultSet *resultSet = [db executeQuery:sql];
        while ([resultSet next]) {
            retStatus = [resultSet intForColumn:@"t_status"];
        }
    }];
    return retStatus;
}
// MARK: - 根据交易ID获取单条交易
- (ZYPurchaseTransactionModel *)queryTransactionModelByTransactionId:(nonnull NSString *)transactionId{
    if (transactionId.length == 0) {
        return nil;
    }
    __block ZYPurchaseTransactionModel *retModel = nil;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSString *sql = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE transaction_id = '%@' limit 0,1", ZYPurchaseTableName, transactionId];
        FMResultSet *resultSet = [db executeQuery:sql];
        while ([resultSet next]) {
            retModel = [ZYPurchaseTransactionModel modelFromResultSet:resultSet];
        }
    }];
    return retModel;
}


// MARK: - 获取本地所有的交易
- (NSArray <ZYPurchaseTransactionModel *>*)queryAllTransactionModels{
    __block NSMutableArray *retArr = @[].mutableCopy;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSString *sql = [NSString stringWithFormat:@"SELECT * FROM %@ ORDER BY update_time DESC", ZYPurchaseTableName];
        FMResultSet *resultSet = [db executeQuery:sql];
        while ([resultSet next]) {
            ZYPurchaseTransactionModel *transactionModel = [ZYPurchaseTransactionModel modelFromResultSet:resultSet];
            if (transactionModel) {
                [retArr addObject:transactionModel];
            }
        }
    }];
    return retArr;
}

/// 获取本地所有的交易（未校验收据的）
- (NSArray <ZYPurchaseTransactionModel *>*)queryAllTransactionModelsUnVerifyReceipt{
    __block NSMutableArray *retArr = @[].mutableCopy;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSString *sql = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE t_status == 7 ORDER BY update_time DESC", ZYPurchaseTableName];
        FMResultSet *resultSet = [db executeQuery:sql];
        while ([resultSet next]) {
            ZYPurchaseTransactionModel *transactionModel = [ZYPurchaseTransactionModel modelFromResultSet:resultSet];
            if (transactionModel) {
                [retArr addObject:transactionModel];
            }
        }
    }];
    return retArr;
}

// MARK: - 更新交易状态信息
- (BOOL)updateTransactionModelStatus:(nonnull ZYPurchaseTransactionModel *)transactionModel{
    if (!transactionModel.isValuable) {
        return NO;
    }
    // 如果不存在则插入此模型
    if (![self existTransactionModel:transactionModel.orderId]) {
        ZYPurchaseTransactionModel *insertModel = [self insertTransactionModel:transactionModel];
        return insertModel?YES:NO;
    }
    __block BOOL result = NO;
    double timeStamp = [[NSDate date] timeIntervalSince1970];
    transactionModel.updateTime = timeStamp;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSArray *params = @[@"t_status",
                            @"update_time",
                            @"error",
                            @"order_info",
                            @"transaction_id",
                            @"receipt_data"];
        NSString *paramsSqlComp = nil;
        for (NSInteger idx = 0; idx < params.count; idx++) {
            NSString *partComp = [NSString stringWithFormat:@"%@ = ?", params[idx]];
            if (!paramsSqlComp) {
                paramsSqlComp = partComp;
            } else {
                paramsSqlComp = [paramsSqlComp stringByAppendingFormat:@", %@", partComp];
            }
        }
        if (!paramsSqlComp) {
            result = NO;
        } else {
            NSString *receipt_dataStr = @"";
            if (transactionModel.receipt_data_filename && (transactionModel.receipt_data_filename.length > 0)) {
                receipt_dataStr = transactionModel.receipt_data_filename;
            }
            NSString *sql = [NSString stringWithFormat:@"UPDATE %@ SET %@ WHERE id = ?", ZYPurchaseTableName, paramsSqlComp];
            NSString *transactionId = @"";
            if (transactionModel.transactionId && (transactionModel.transactionId.length > 0)) {
                transactionId = transactionModel.transactionId;
            }
            result = [db executeUpdate:sql, @(transactionModel.transactionStatus), @(transactionModel.updateTime), transactionModel.error, transactionModel.order.mj_JSONString, transactionId, receipt_dataStr,  @(transactionModel.sql_id)];
        }
    }];
    return result;
}

// MARK: - 添加交易
- (ZYPurchaseTransactionModel *)insertTransactionModel:(nonnull ZYPurchaseTransactionModel *)transactionModel{
    if (!transactionModel.isValuable) {
        NSLog(@"交易模型信息异常，不能插入数据库");
        return nil;
    }
    // 如果已存在此模型则返回已插入的模型
    if ([self existTransactionModel:transactionModel.orderId]) {
        return [self queryTransactionModel:transactionModel.orderId];
    }
    double timeStamp = [[NSDate date] timeIntervalSince1970];
    transactionModel.createTime = timeStamp;
    transactionModel.updateTime = timeStamp;
    __block BOOL result = NO;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSArray *params = @[@"t_status",
                            @"receipt_data",
                            @"order_info",
                            @"payment_method",
                            @"error",
                            @"uuid",
                            @"order_id",
                            @"transaction_id",
                            @"create_time",
                            @"update_time"];
        NSString *paramsStr = [params componentsJoinedByString:@", "];
        NSString *valuesStr = @"?";
        if (params.count > 1) {
            for (NSInteger idx = 1; idx < params.count; idx++) {
                valuesStr = [valuesStr stringByAppendingFormat:@", ?"];
            }
        }
        NSString *receipt_dataStr = @"";
        if (transactionModel.receipt_data_filename && (transactionModel.receipt_data_filename.length > 0)) {
            receipt_dataStr = transactionModel.receipt_data_filename;
        }
        NSString *sql = [NSString stringWithFormat:@"INSERT INTO %@ (%@) VALUES (%@)", ZYPurchaseTableName, paramsStr, valuesStr];
        result = [db executeUpdate:sql, @(transactionModel.transactionStatus), receipt_dataStr, transactionModel.order.mj_JSONString, @(transactionModel.paymentMethod), transactionModel.error, transactionModel.uuid, transactionModel.orderId, transactionModel.transactionId, @(transactionModel.createTime), @(transactionModel.updateTime)];
    }];
    if (!result) {
        return nil;
    }
    return [self queryTransactionModel:transactionModel.orderId];
}

// MARK: - 根据orderId删除某条交易记录
- (BOOL)deleteTransactionModel:(nonnull NSString *)orderId{
    __block BOOL exist = [self existTransactionModel:orderId];
    if (!exist) {
        return NO;
    }
    __block BOOL result = NO;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSString *sql = [NSString stringWithFormat:@"DELETE FROM %@ WHERE order_id = '%@'", ZYPurchaseTableName, orderId];
        result = [db executeUpdate:sql];
    }];
    return result;
}

- (FMDatabaseQueue *)dbQueue{
    if (_dbQueue == nil) {
        _dbQueue = [FMDatabaseQueue databaseQueueWithPath:[self sqliteFilePath]];
    }
    return _dbQueue;
}
// 数据库路径
- (NSString *)sqliteFilePath{
    return [[self class].purchaseDirectoryPath stringByAppendingPathComponent:ZYPurchaseSqliteName];
}
// 购买模块专用文件夹
+ (NSString *)purchaseDirectoryPath{
    NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    return [documents stringByAppendingPathComponent:ZYPurchaseDirectory];
}
// 购买收据专用文件夹
+ (NSString *)purchaseReceiptDirectoryPath{
    return [[self purchaseDirectoryPath] stringByAppendingPathComponent:@"receipt"];
}
// log文件专用文件夹
+ (NSString *)logFileDirectoryPath{
    return [[self purchaseDirectoryPath] stringByAppendingPathComponent:@"log"];
}

// 删除表
- (BOOL)dropTable:(NSString *)tableName{
    __block BOOL retsult = NO;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSString *sql = [NSString stringWithFormat:@"DROP TABLE %@", tableName];
        retsult = [db executeUpdate:sql];
    }];
    return retsult;
}

/// 恢复旧表数据
- (BOOL)restorePublishModelsInOldTablesIfNeeded{
    return NO;
//    NSString *previousTbaleName = [self previousTbaleName];
//    // 检测是否有旧表存在
//    if (!previousTbaleName || (previousTbaleName.length == 0)) {
//        return YES;
//    }
    // 旧表存在
    // 第一步：获取数据
//    NSArray *models = [self fetchAllPublishModelsWithTableName:previousTbaleName];
//    // 第二步：删除表
//    BOOL dropResult = [self dropTable:previousTbaleName];
//    __block BOOL insertResult = YES;
//    // 第三步：旧表插入到新表
//    if (models.count > 0) {
//        double timeStamp = [[NSDate date] timeIntervalSince1970];
//        [self.dbQueue inTransaction:^(FMDatabase * _Nonnull db, BOOL * _Nonnull rollback) {
//            for (NSInteger idx = 0; idx < models.count; idx++) {
//                ZYCommunityPublishModel *publishModel = models[idx];
//                publishModel.createTime = timeStamp;
//                publishModel.updateTime = timeStamp;
//                NSString *sql = [NSString stringWithFormat:@"insert into %@ (title, publish_des, cover_location, state, video_filename, cover_filename, json_filename, aliyunpath_cover, aliyunpath_video, tags, devices, longitude, latitude, address, need_save_album, create_time, update_time, error, shot_num, duration, video_identifiers, draft_id, source_type, video_preset, local_identifier) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", ZYCommunityPublishTableName];
//                BOOL result = [db executeUpdate:sql, publishModel.title, publishModel.publish_des, @(publishModel.coverLocation), @(publishModel.state), publishModel.videoFileName, publishModel.coverName, publishModel.jsonFileName, publishModel.aLiYunPath_Cover, publishModel.aLiYunPath_Video, publishModel.tagsString, publishModel.devicesString, @(publishModel.longitude), @(publishModel.latitude), publishModel.address, @(publishModel.needSaveAlbum), @(publishModel.createTime), @(publishModel.updateTime), publishModel.publish_error, @(publishModel.shotNum), @(publishModel.duration), publishModel.videoIdentifiers, @(publishModel.draft_id), @(publishModel.sourceType), @(publishModel.videoPreset), publishModel.localIdentifier_InPhotoApp];
//                if (!result) {
//                    insertResult = NO;
//                }
//            }
//        }];
//    }
//    return (insertResult && dropResult);
}

// 上个版本表名称
- (NSString *)previousTbaleName{
    NSString *retName = nil;
    NSString *prefixTableName = @"communityPublishTable_V";
    int versionNum = [[ZYPurchaseTableName substringFromIndex:prefixTableName.length] intValue];
    for (NSInteger idx = 0; idx < versionNum; idx++) {
        NSString *tableName = (idx == 0)?@"communityPublishTable":[NSString stringWithFormat:@"%@%ld", prefixTableName, (long)idx];
        if ([self tableExist:tableName]) {
            retName = tableName;
            break;
        }
    }
    return retName;
}

- (BOOL)tableExist:(NSString *)tableName{
    if (!tableName || (tableName.length == 0)) {
        return NO;
    }
    __block BOOL retValue = NO;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        retValue = [db tableExists:tableName];
    }];
    return retValue;
}
/// 创建一个文件夹
+ (BOOL)zy_createDirectoryWhenNotExistsAtPath:(NSString *)filePath {
    if (![self isAvailableFilePath:filePath]) {
        return NO;
    }
    if (![self zy_fileExists:filePath]) {
        NSError *error;
        BOOL succ = [[NSFileManager defaultManager] createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:&error];
        if (!succ) {
            NSLog(@"error create path!");
            if (error) {
                NSLog(@"create file path error: %@", error);
            }
            return NO;
        }
    }
    
    return YES;
}
+ (BOOL)zy_fileExists:(NSString *)filePath{
    if (![self isAvailableFilePath:filePath]) {
        return NO;
    }
    BOOL isDirectory = NO;
    BOOL isExist = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory];
    
    return isExist && !isDirectory;
}
+ (BOOL)isAvailableFilePath:(NSString *)filePath {
    if (!filePath || (![filePath isKindOfClass:[NSString class]]) || (filePath.length == 0)) {
        return NO;
    }
    return YES;
}

static NSString *kZYPurchageService = @"com.zhiyun.ZYPurchage.LastIAPApplicationUsername";
static NSString *kZYPurchageAccount = @"com.zhiyun.ZYPurchage";
// 重置上一次内购 applicationUsername
+ (BOOL)resetLastIAPApplicationUsernameInKeychain:(nonnull NSString *)applicationUsername{
    if (!applicationUsername || (applicationUsername.length == 0)) {
        return NO;
    }
    NSError *error = nil;
    BOOL result = [SAMKeychain setPassword:applicationUsername forService:kZYPurchageService account:kZYPurchageAccount error:&error];
    if (error) {
        NSLog(@"IAP:  存储 applicationUsername 失败：%@", error);
    }
    return result;
}
// 清空 applicationUsername
+ (BOOL)clearLastIAPApplicationUsernameInKeychain{
    return [SAMKeychain deletePasswordForService:kZYPurchageService account:kZYPurchageAccount];
}
// 获取上次设置的 applicationUsername
+ (nullable NSString *)lastIAPApplicationUsernameInKeychain{
    return [SAMKeychain passwordForService:kZYPurchageService account:kZYPurchageAccount];
}

@end

@implementation ZYPurchaseDataBase (Receipt)


/// 查看收据是否已经存在
- (BOOL)receiptsFileNameExist:(NSString *)receiptFileName{
    __block BOOL result = NO;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSString *sql = [NSString stringWithFormat:@"SELECT file_name FROM %@ WHERE file_name = '%@' limit 0,1", ZYPurchaseTableName_receipt, receiptFileName];
        FMResultSet *resultSet = [db executeQuery:sql];
        while ([resultSet next]) {
            result = YES;
        }
    }];
    return result;
}
/// 获取所有暂存未校验成功的收据   [查]
- (nullable NSArray *)fetchUnVerifyReceipts{
    __block NSMutableArray *retArr = @[].mutableCopy;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSString *sql = [NSString stringWithFormat:@"SELECT * FROM %@", ZYPurchaseTableName_receipt];
        FMResultSet *resultSet = [db executeQuery:sql];
        while ([resultSet next]) {
            NSInteger sql_id = [resultSet intForColumn:@"id"];
            NSString *file_name = [resultSet stringForColumn:@"file_name"];
            NSString *order_id = [resultSet stringForColumn:@"order_id"];
            if (file_name && (file_name.length > 0) &&
                order_id && (order_id.length > 0)) {
                NSMutableDictionary *mDict = @{}.mutableCopy;
                mDict[@"id"] = @(sql_id);
                mDict[@"file_name"] = file_name;
                mDict[@"order_id"] = order_id;
                [retArr addObject:mDict];
            }
        }
    }];
    return retArr;
}


/// 移除收据，校验成功后     [删]
- (BOOL)reVerifyReceiptsSuccess:(NSString *)receiptFileName{
    if (!receiptFileName || !(receiptFileName.length > 0)) {
        return NO;
    }
    if (![self receiptsFileNameExist:receiptFileName]) {
        return NO;
    }
    __block BOOL result = NO;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSString *sql = [NSString stringWithFormat:@"DELETE FROM %@ WHERE file_name = '%@'", ZYPurchaseTableName_receipt, receiptFileName];
        result = [db executeUpdate:sql];
    }];
    NSLog(@"IAP: 删除了收据 %@,  %@", receiptFileName, result?@"成功":@"失败");
    return result;
}

/// 暂存未校验的收据   [增]
/// @param receiptFileName 收据文件名
/// @param orderId 订单id
- (BOOL)storageUnVerifyReceipt:(nonnull NSString *)receiptFileName
                       orderId:(nullable NSString *)orderId{
    if (!receiptFileName || !(receiptFileName.length > 0)) {
        return NO;
    }
    if ([self receiptsFileNameExist:receiptFileName]) {
        return NO;
    }
    if (!orderId || (orderId.length == 0)) {
        orderId = @"";
    }
    __block BOOL result = NO;
    [self.dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
        NSArray *params = @[@"file_name",
                            @"order_id"];
        NSString *paramsStr = [params componentsJoinedByString:@", "];
        NSString *valuesStr = @"?";
        if (params.count > 1) {
            for (NSInteger idx = 1; idx < params.count; idx++) {
                valuesStr = [valuesStr stringByAppendingFormat:@", ?"];
            }
        }
        NSString *sql = [NSString stringWithFormat:@"INSERT INTO %@ (%@) VALUES (%@)", ZYPurchaseTableName_receipt, paramsStr, valuesStr];
        result = [db executeUpdate:sql, receiptFileName, orderId];
    }];
    if (result) {
        
    }
    NSLog(@"IAP: 存储了收据 %@,  %@", receiptFileName, result?@"成功":@"失败");
    return result;
}

@end
